home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
edit
/
jwpsrc.zip
/
UNDO.C
< prev
Wrap
C/C++ Source or Header
|
1993-03-31
|
27KB
|
1,066 lines
/* Copyright (C) Stephen Chung, 1991-1993. All rights reserved. */
#include "jwp.h"
static PARAGRAPH far *fpara = NULL;
void FreeUndo (UNDOBUF far *up)
{
switch (up->action) {
U_PARAFORMAT:
U_INSERT:
U_DELETE:
U_REPLACE: {
PARAGRAPH far *lp, far *lp2;
for (lp = (PARAGRAPH far *) up->data; lp != NULL; ) {
if (lp->text != NULL) FreeBlock(lp->text);
lp2 = lp;
lp = lp->next;
FreeBlock(lp2);
}
}
}
FreeBlock(up);
}
void FreeUndoChain (UNDOBUF far *up)
{
UNDOBUF far *up1;
for (; up != NULL; ) {
up1 = up;
up = up->next;
FreeUndo(up1);
}
}
static int FindParaNum (FILEOPTIONS *f, PARAGRAPH far *p)
{
int n;
PARAGRAPH far *p1;
for (p1 = f->paragraph, n = 0; p1 != NULL; p1 = p1->next, n++) {
if (p1 == p) return (n);
}
return (-1);
}
void TrimUndoChain (FILEOPTIONS *f)
{
UNDOBUF far *up;
if (f->undo == NULL) return;
while (f->undolevels > global.undolevels) {
if (f->undo->next == NULL) {
FreeUndo(f->undo);
f->undo = f->undotail = NULL;
f->undolevels = 0;
return;
}
up = f->undotail->prev;
FreeUndo(f->undotail);
if (up == NULL) {
f->undo = f->undotail = NULL;
f->undolevels = 0;
} else {
up->next = NULL;
f->undotail = up;
f->undolevels--;
}
}
}
static UNDOBUF far *CreateUndo (int para, int start, int len, UNDOACTIONS action)
{
UNDOBUF far *up;
up = StructAlloc(UNDOBUF);
up->para1 = up->para2 = para;
up->start = start;
up->stop = start + len;
up->action = action;
up->data = NULL;
up->next = up->prev = NULL;
return (up);
}
void UndoAddTyping (FILEOPTIONS *f, POSITION p, int howmany, BOOL splitline)
{
int para, start;
UNDOBUF far *up;
time_t tm;
if (global.undolevels == 0) return;
if (!(f->type & FN_NORMAL)) return;
FreeUndoChain(f->redo);
f->redo = NULL;
para = FindParaNum(f, PARAOF(p));
start = POS2ABS(p);
up = f->undo;
if (splitline) {
if (up == NULL) {
up = f->undo = f->undotail = CreateUndo(para, start, 0, U_INSERT);
up->para2 = para + 1;
up->stop = 0;
f->undolevels = 1;
} else if ((up->action == U_INSERT || up->action == U_REPLACE) &&
up->para2 == para && up->stop == start) {
up->para2 = para + 1;
up->stop = 0;
} else {
up = CreateUndo(para, start, 0, U_INSERT);
up->para2 = para + 1;
up->stop = 0;
up->next = f->undo;
f->undo->prev = up;
f->undo = up;
f->undolevels++;
TrimUndoChain(f);
}
} else {
if (up == NULL) {
up = f->undo = f->undotail = CreateUndo(para, start, howmany, U_INSERT);
f->undolevels = 1;
} else if ((up->action != U_INSERT && up->action != U_REPLACE) ||
up->para2 != para || up->stop != start) {
up = CreateUndo(para, start, howmany, U_INSERT);
up->next = f->undo;
f->undo->prev = up;
f->undo = up;
f->undolevels++;
TrimUndoChain(f);
} else {
up->stop += howmany;
}
}
time(&tm);
up->time = tm;
}
void UndoFixConvert (FILEOPTIONS *f, POSITION p, int oldlen, int newlen)
{
UNDOBUF far *up;
time_t tm;
if (global.undolevels == 0) return;
if (f->undo == NULL) return;
if (!(f->type & FN_NORMAL)) return;
up = f->undo;
if (up->action != U_INSERT && up->action != U_REPLACE) return;
if (up->para2 != FindParaNum(f, PARAOF(p))) return;
//if (up->stop != POS2ABS(p) + oldlen) return;
if (up->stop <= POS2ABS(p)) return;
up->stop += newlen - oldlen;
time(&tm);
up->time = tm;
}
void UndoAddInsert (FILEOPTIONS *f, POSITION p1, POSITION p2)
{
UNDOBUF far *up;
int para1, para2;
time_t tm;
if (global.undolevels == 0) return;
if (!(f->type & FN_NORMAL)) return;
FreeUndoChain(f->redo);
f->redo = NULL;
para1 = FindParaNum(f, PARAOF(p1));
para2 = FindParaNum(f, PARAOF(p2));
if (f->undo == NULL) {
up = f->undo = f->undotail = CreateUndo(para1, POS2ABS(p1), 0, U_INSERT);
up->para2 = para2;
up->stop = POS2ABS(p2);
f->undolevels = 1;
} else {
up = CreateUndo(para1, POS2ABS(p1), 0, U_INSERT);
up->para2 = para2;
up->stop = POS2ABS(p2);
up->next = f->undo;
f->undo->prev = up;
f->undo = up;
f->undolevels++;
TrimUndoChain(f);
}
time(&tm);
up->time = tm;
}
static PARAGRAPH far *SaveData (FILEOPTIONS *f, POSITION p1, POSITION p2)
{
unsigned int len;
PARAGRAPH far *data = NULL, far *p, far *lp;
if (PARAOF(p1) == PARAOF(p2)) {
lp = StructAlloc(PARAGRAPH);
_fmemcpy(lp, PARAOF(p1), sizeof(PARAGRAPH));
lp->lines = lp->lastline = NULL;
lp->next = lp->prev = NULL;
len = POSOF(p2) - POSOF(p1);
lp->textsize = (len + 2) * sizeof(UNIT);
lp->text = BlockAlloc(lp->textsize);
_fmemcpy(lp->text, PARAOF(p1)->text + POSOF(p1), len * sizeof(UNIT));
lp->text[len].kanji = 0;
return (lp);
}
for (p = PARAOF(p1); ; p = p->next) {
if (data == NULL) {
data = lp = StructAlloc(PARAGRAPH);
_fmemcpy(lp, p, sizeof(PARAGRAPH));
lp->prev = NULL;
} else {
lp->next = StructAlloc(PARAGRAPH);
_fmemcpy(lp->next, p, sizeof(PARAGRAPH));
lp->next->prev = lp;
lp = lp->next;
}
lp->next = NULL;
lp->lines = lp->lastline = NULL;
if (p == PARAOF(p1)) {
len = unitlen(p->text) - POSOF(p1);
lp->textsize = (len + 2) * sizeof(UNIT);
lp->text = BlockAlloc(lp->textsize);
_fmemcpy(lp->text, p->text + POSOF(p1), len * sizeof(UNIT));
lp->text[len].kanji = 0;
} else if (p == PARAOF(p2)) {
len = POSOF(p2);
lp->textsize = (len + 2) * sizeof(UNIT);
lp->text = BlockAlloc(lp->textsize);
_fmemcpy(lp->text, p->text, len * sizeof(UNIT));
lp->text[len].kanji = 0;
break;
} else {
len = unitlen(p->text);
lp->textsize = (len + 2) * sizeof(UNIT);
lp->text = BlockAlloc(lp->textsize);
_fmemcpy(lp->text, p->text, len * sizeof(UNIT));
lp->text[len].kanji = 0;
}
}
return (data);
}
void UndoAddDelete (FILEOPTIONS *f, POSITION p1, POSITION p2)
{
UNDOBUF far *up;
int para1, para2;
time_t tm;
if (global.undolevels == 0) return;
if (!(f->type & FN_NORMAL)) return;
FreeUndoChain(f->redo);
f->redo = NULL;
para1 = FindParaNum(f, PARAOF(p1));
POSOF(p1) = POS2ABS(p1);
para2 = FindParaNum(f, PARAOF(p2));
POSOF(p2) = POS2ABS(p2);
if (f->undo == NULL) {
up = f->undo = f->undotail = CreateUndo(para1, POSOF(p1), 0, U_DELETE);
up->para2 = para2;
up->stop = POSOF(p2);
f->undolevels = 1;
} else {
up = CreateUndo(para1, POSOF(p1), 0, U_DELETE);
up->para2 = para2;
up->stop = POSOF(p2);
up->next = f->undo;
f->undo->prev = up;
f->undo = up;
f->undolevels++;
TrimUndoChain(f);
}
up->data = SaveData(f, p1, p2);
time(&tm);
up->time = tm;
}
void UndoJoinLine (FILEOPTIONS *f, POSITION p)
{
int para, start;
UNDOBUF far *up;
PARAGRAPH far *pp;
time_t tm;
if (global.undolevels == 0) return;
if (!(f->type & FN_NORMAL)) return;
para = FindParaNum(f, PARAOF(p));
start = POS2ABS(p);
up = f->undo;